package offer;

import com.netscenery.yang.model.DataDefElement;
import com.netscenery.yang.model.ModelElement;
import com.netscenery.yang.model.Module;
import com.netscenery.yang.model.Node;



public class ConvertToJson {
	private Module module;
	private StringBuilder jsonString;
	public  ConvertToJson(){
	}
	public  ConvertToJson(Module module){
		this.module = module;
	}
	
	
	public String getModuleTree(){
		convertMoudleToTree();
		return jsonString.toString();
	}
	
	
	/**********************************************************************************************************
	 ********************************************************************************************************** 
	 *****                                convert Notes Begin  
	 **********************************************************************************************************
	 ***********************************************************************************************************/
	private String getDataDefs(Module module){
		StringBuilder jsonStr = new StringBuilder();
		
		if( module.getDataDefsNumber() > 0 ){
			
			int isLastChild = 0;
			for(int i = 0; i < module.getDataDefsNumber(); i++){
				isLastChild = (i ==(module.getDataDefsNumber()-1)?1:0);
				jsonString.append((getDataDefChild(module.getDataDef(i) ,isLastChild ,"Note")));
			}
			
		}
		return jsonStr.toString();
	}
	/*
	 * isLastChild �ж��ǲ������һ�����ӽ�㣬0 ���ǣ�1 ��
	 */
	private String getDataDefChild(DataDefElement itemNode , int isLastChild, String levelStr){
		
		StringBuilder jsonStr = new StringBuilder();
		String simpleName = itemNode.getClass().getSimpleName();          //���浱ǰ��������

		String levelCur = levelStr + "\\\\" + itemNode.getName();   
		//���浱ǰ�����Ĳ��
		if(itemNode instanceof Node){
			if(((Node) itemNode).isKey()){
				simpleName = "leaf-key";
			}
		}
		
		jsonStr.append("{\"data\":{\"title\":\""+itemNode.getName()+"\",\"icon\" :\"images/"+simpleName+".jpg\"},\"attr\":{\"id\":\""+levelCur+"\",\"className\":\""+itemNode.getClass().getName()+"\"}");
		if (itemNode instanceof Node){
			if(0 != ((Node) itemNode).getSonsNumber()){
				jsonStr.append(",\"children\":[");
				int inner_isLastChild = 0;
				for(int i = 0; i < ((Node) itemNode).getSonsNumber(); i++){
					inner_isLastChild = (i ==((Node) itemNode).getSonsNumber()?1:0);
					jsonStr.append((getDataDefChild(((Node) itemNode).getSon(i) ,inner_isLastChild , levelCur)));
				}
				jsonStr.append("]");
			}
		}
		
		
		if(0 == isLastChild){
			jsonStr.append("},");
		}else{
			jsonStr.append("}");
		}
		
		return jsonStr.toString();
	}
	//�ṩ����Ľӿ�
	public String getChilds(Node itemNode ,  String levelStr){
		StringBuilder jsonStr = new StringBuilder();
		int inner_isLastChild = 0;
		jsonStr.append("[");
		for(int i = 0; i < itemNode.getSonsNumber(); i++){
			inner_isLastChild = (i ==(itemNode.getSonsNumber()-1)?1:0);
			jsonStr.append((getDataDefChild(itemNode.getSon(i) ,inner_isLastChild , levelStr)));
		}
		jsonStr.append("]");
		return jsonStr.toString();
	}
	
	/**********************************************************************************************************
	 ********************************************************************************************************** 
	 *****                                convert Notes End  
	 **********************************************************************************************************
	 ***********************************************************************************************************/
	
	/* ********************************************************************************************************
	 ********************************************************************************************************** 
	 *****                                convert Element Begin  
	 **********************************************************************************************************
	 ***********************************************************************************************************/
    /**
     * Includes
     * @param module
	 * @return
     */
	private String getIncludes(Module module){
		
		StringBuilder jsonStr = new StringBuilder();
		if( 0 < module.getIncludesNumber()){
			for(int i = 0 ; i < module.getIncludesNumber() ; i++ ){
				jsonStr.append(getItems(module.getInclude(i)));
			}
		}
		
		return jsonStr.toString();
	}
	/**
	 * Imports
	 * @param module
	 * @return
	 */
	private String getImports(Module module){
		StringBuilder jsonStr = new StringBuilder();
		if( 0 < module.getImportsNumber()){
			for(int i = 0 ; i < module.getImportsNumber() ; i++ ){
				jsonStr.append(getItems(module.getImport(i)));
			}
		}
		return jsonStr.toString();
	}
	/**
	 * Revisions
	 * @param module
	 * @return
	 */
	private String getRevisions(Module module){
		StringBuilder jsonStr = new StringBuilder();
		if( 0 < module.getRevisionsNumber()){
			for(int i = 0 ; i < module.getRevisionsNumber() ; i++ ){
				jsonStr.append(getItems(module.getRevision(i)));
			}
		}
		return jsonStr.toString();
	}
	/**
	 * Extensions
	 * @param module
	 * @return
	 */
	private String getExtensions(Module module){
		StringBuilder jsonStr = new StringBuilder();
		if( 0 < module.getExtensionsNumber()){
			for(int i = 0 ; i < module.getExtensionsNumber() ; i++ ){
				jsonStr.append(getItems(module.getExtension(i)));
			}
		}
		return jsonStr.toString();
	}
	/**
	 * Typedefs
	 * @param module
	 * @return
	 */
	private String getTypedefs(Module module){
		StringBuilder jsonStr = new StringBuilder();
		if( 0 < module.getTypedefsNumber()){
			for(int i = 0 ; i < module.getTypedefsNumber() ; i++ ){
				jsonStr.append( getItems(module.getTypedef(i)));
			}
		}
		return jsonStr.toString();
	}
	/**
	 * Features
	 * @param module
	 * @return
	 */
	private String getFeatures(Module module){
		StringBuilder jsonStr = new StringBuilder();
		for(int i = 0 ; i < module.getFeaturesNumber() ; i++){
			jsonStr.append( getItems(module.getFeature(i)));
		}
		return jsonStr.toString();
	}
	/**
	 * Deviation
	 * @param module
	 * @return
	 */
	private String getDeviation(Module module){
		StringBuilder jsonStr = new StringBuilder();
		for(int i = 0; i < module.getDeviationsNumber(); i++ ){
			jsonStr.append(getDeviationItems(module.getDeviation(i)));
		}
		return jsonStr.toString();
	}
	private String getItems(ModelElement element){
		StringBuilder jsonStr = new StringBuilder();
		String idString    = "ModelElement@" +element.getClass().getSimpleName()+ "@"+ element.getName();
		jsonStr.append("{\"data\":{\"title\":\""+element.getName()+"\",\"icon\" :\"images/"+element.getClass().getSimpleName()+".jpg\"},\"attr\":{\"id\":\""+idString+"\",\"className\":\""+element.getClass().getName()+"\"}");
		jsonStr.append("},");
		return jsonStr.toString();
	}
	
	private String getDeviationItems(ModelElement element){
		StringBuilder jsonStr = new StringBuilder();
		String idString    = "ModelElement@" +element.getClass().getSimpleName()+ "@"+ element.getName();
		String [] nodes    =  element.getName().split("/");
		String name        = "deviation@"+nodes[nodes.length-1];
		jsonStr.append("{\"data\":{\"title\":\""+name+"\",\"icon\" :\"images/"+element.getClass().getSimpleName()+".jpg\"},\"attr\":{\"id\":\""+idString+"\",\"className\":\""+element.getClass().getName()+"\"}");
		jsonStr.append("},");
		return jsonStr.toString();
	}
	
    private void dealWithString(Module module){
    	
    	int moduleElemnet_lenght = module.getIncludesNumber() + module.getImportsNumber() + module.getRevisionsNumber() +
    	module.getExtensionsNumber() + module.getExtensionsNumber() + module.getTypedefsNumber();
    	
    	int node_length = module.getDataDefsNumber();
    	
    	if((moduleElemnet_lenght > 0) && node_length == 0){
    		jsonString = new StringBuilder(jsonString.substring(0, jsonString.length()-1));
    	}
    	
    }
    /* ********************************************************************************************************
	 ********************************************************************************************************** 
	 *****                                convert Element End                                             *****
	 **********************************************************************************************************
	 ***********************************************************************************************************/
    
    
    private String convertMoudleToTree(){
    	jsonString =  new StringBuilder();
    	int moduleElemnet_lenght = module.getIncludesNumber() + module.getImportsNumber() + module.getRevisionsNumber() +
    	module.getExtensionsNumber() + module.getExtensionsNumber() + module.getTypedefsNumber() + module.getDataDefsNumber() +
    	module.getFeaturesNumber();
		jsonString.append("[");
		jsonString.append("{\"data\":{\"title\":\""+module.getName()+"\",\"icon\" :\"images/module.jpg\"},\"attr\":{\"id\":\"Module\",\"className\":\""+module.getClass().getName()+"\"}");
		if(  moduleElemnet_lenght > 0 ){
			jsonString.append(",\"children\":[");
			jsonString.append(getIncludes(module));
			jsonString.append(getImports(module));
			jsonString.append(getRevisions(module));
			jsonString.append(getExtensions(module));
			jsonString.append(getTypedefs(module));
			jsonString.append(getFeatures(module));
			jsonString.append(getDeviation(module));
			dealWithString(module);
			//���Nodes ������
			jsonString.append(getDataDefs(module));
			jsonString.append("]");
		}
		
		jsonString.append(",\"state\":\"open\"");
		jsonString.append("}");
		jsonString.append("]");
		
		return jsonString.toString();
    }
	
}
